package com.zhuss.core.processor;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.zhuss.bean.bo.core.login.LoginBo;
import com.zhuss.bean.bo.core.login.TokenBo;
import com.zhuss.bean.bo.core.user.wechat.BindUserOpenIdBo;
import com.zhuss.bean.unit.core.user.UserBean;
import com.zhuss.bean.vo.core.company.DetailCompanyVo;
import com.zhuss.bean.vo.core.login.LoginVo;
import com.zhuss.bean.vo.core.user.DetailUserVo;
import com.zhuss.common.AbstractProcessor;
import com.zhuss.common.ListVo;
import com.zhuss.common.Processor;
import com.zhuss.core.db.dao.ext.UserDao;
import com.zhuss.core.db.entity.User;
import com.zhuss.db.entity.OpLog;
import com.zhuss.enums.IsEnum;
import com.zhuss.enums.LogActionEnum;
import com.zhuss.enums.MoudleEnum;
import com.zhuss.enums.SystemEnum;
import com.zhuss.exception.AabException;
import com.zhuss.exception.ExceptionCode;
import com.zhuss.util.JsonUtil;
import com.zhuss.util.PwdUtil;

/**
 * 登录 processor
 * @Author: zhushanshuo
 * @Date: 2019/12/24 17:55
 */
@Component("loginProcessor")
public class LoginProcessor extends AbstractProcessor<LoginVo, LoginBo> implements Processor<LoginVo, LoginBo> {

	@Autowired
	@Qualifier("userRead")
	private UserRead userRead;
	
	@Autowired
	private UserDao userDao;
	
	@Autowired
	@Qualifier("companyRead")
	private CompanyRead companyRead;
	
	@Autowired
	@Qualifier("userRoleRead")
	private UserRoleRead userRoleRead;
	
	@Autowired
	@Qualifier("roleRead")
	private RoleRead roleRead;
	
	@Autowired
	@Qualifier("loginRedis")
	private Processor<Void, TokenBo> loginRedis;
	
	@Autowired
	@Qualifier("userOpenIdBind")
	private Processor<Object, BindUserOpenIdBo> userOpenIdBind;
	
    /**
     * 校验
     */
    @Override
    public void check(LoginBo bo) throws AabException {
    	String username = bo.getUsername();
    	String pwd = bo.getPwd();
    	String openId = bo.getOpenId();
    	Integer system = bo.getConcurrentSystem();
    	if (username == null || "".equals(username.trim()) 
    			|| pwd == null || "".equals(pwd.trim())) {
    		throw new AabException(ExceptionCode.用户名或密码为空);
    	}
    	
    	if ((openId == null || "".equals(openId.trim())) 
    			&& SystemEnum.小程序.sameKey(system)) {
    		throw new AabException(ExceptionCode.OPEN_ID为空);
    	}
    	
    	List<User> userList = userRead.login(username, PwdUtil.md5(pwd));
    	if (userList.isEmpty() || userList.size() > 1) {
    		throw new AabException(ExceptionCode.用户名或密码错误);
    	}
    	
    	UserBean user = new UserBean();
    	User userDb = userList.get(0);
    	bo.setTargetId(userDb.getUserId());
    	BeanUtils.copyProperties(userDb, user);
    	bo.setUser(user);
    	if (PwdUtil.init().equals(pwd)) {
    		user.setIsNeedUpdatePwd(IsEnum.是.key());
    	}
    	
    	Long companyId = user.getCompanyId();
    	DetailCompanyVo company = (DetailCompanyVo) companyRead.detail(companyId);
    	String companyName = company.getName();
    	user.setCompanyName(companyName);
    }
    
    /**
     * 操作方法
     * @throws AabException 
     */
    @SuppressWarnings("unchecked")
	@Override
    public LoginVo process(LoginBo bo) throws AabException {
    	String openId = bo.getOpenId();
    	String token = openId == null || "".equals(openId.trim()) ? UUID.randomUUID().toString() : openId;
    	UserBean user = bo.getUser();
    	Long userId = user.getUserId();
    	LoginVo result = new LoginVo();
    	result.setUser(user);
    	result.setToken(token);
    	
    	if (SystemEnum.小程序.sameKey(bo.getConcurrentSystem())) {
    		BindUserOpenIdBo bindUserOpenIdBo = new BindUserOpenIdBo();
    		BeanUtils.copyProperties(bo, bindUserOpenIdBo);
    		bindUserOpenIdBo.setUserId(userId);
    		bindUserOpenIdBo.setOpenId(openId);
    		userOpenIdBind.process(bindUserOpenIdBo);
    		user.setOpenId(openId);
    	}
    	// 查询角色
    	List<Long> roleIdList = (List<Long>) userRoleRead.listRoleId(userId);
    	if (roleIdList != null && !roleIdList.isEmpty()) {
    		List<ListVo> roleList = (List<ListVo>) roleRead.getByList(roleIdList);
    		result.setRoleList(roleList);
    	}
    	
    	TokenBo paramToken = new TokenBo();
    	BeanUtils.copyProperties(bo, paramToken);
    	paramToken.setToken(token);
    	paramToken.setUserId(userId);
    	loginRedis.process(paramToken);
    	
    	// app 登录绑定cid
    	String cid = bo.getCid();
    	if (cid != null && !"".equals(cid)) {
    		DetailUserVo userDb = (DetailUserVo) userRead.detail(userId);
    		Set<String> cidDb = userDb.getCid();
    		if (cidDb == null) {
    			cidDb = new HashSet<>();
    		}
    		cidDb.add(cid);
    		StringBuffer sb = new StringBuffer();
    		if (cidDb != null && cidDb.size() > 0) {
    			for (String str : cidDb) {
    				sb.append(str);
    				sb.append(",");
    			}
    			sb.deleteCharAt(sb.lastIndexOf(","));
    		}
    		String cidListStr = sb.toString();
    		User record = new User();
    		record.setUserId(userId);
    		record.setCid(cidListStr);
    		userDao.updateByPrimaryKeySelective(record);
    	}
        return result;
    }
    
    /**
     * 操作日志
     */
	@Override
	public LoginVo log(LoginBo param) throws AabException {
		OpLog record = new OpLog();
    	record.setMoudle(MoudleEnum.基础模块.key());
    	record.setAction(LogActionEnum.登录.key());
    	record.setTargetId(param.getTargetId());
    	record.setTargetName("用户ID:" + param.getTargetId());
    	record.setContent("参数: " + JsonUtil.toJson(param));
    	record.setReason(param.getExceptionReason());
    	
    	record.setCreatorId(param.getTargetId());
    	record.setCreator("用户ID:" + param.getTargetId());
    	record.setCreateTime(new Date());
    	log(record);
    	return null;
	}
}
